{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "name": "sarcasm_glove.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true,
      "include_colab_link": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/lmoroney/tfbook/blob/master/chapter7/sarcasm_glove.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zX4Kg8DUTKWO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "4gs9htvM7n_x",
        "colab": {}
      },
      "source": [
        "# Run this to ensure TensorFlow 2.x is used\n",
        "try:\n",
        "  # %tensorflow_version only exists in Colab.\n",
        "  %tensorflow_version 2.x\n",
        "except Exception:\n",
        "  pass"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "XYYDvoskkE61",
        "colab": {}
      },
      "source": [
        "import json\n",
        "import tensorflow as tf\n",
        "import numpy as np\n",
        "\n",
        "from tensorflow.keras.preprocessing.text import Tokenizer\n",
        "from tensorflow.keras.preprocessing.sequence import pad_sequences"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WpOdgZnNlWY5",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from bs4 import BeautifulSoup\n",
        "import string\n",
        "\n",
        "stopwords = [\"a\", \"about\", \"above\", \"after\", \"again\", \"against\", \"all\", \"am\", \"an\", \"and\", \"any\", \"are\", \"as\", \"at\",\n",
        "             \"be\", \"because\", \"been\", \"before\", \"being\", \"below\", \"between\", \"both\", \"but\", \"by\", \"could\", \"did\", \"do\",\n",
        "             \"does\", \"doing\", \"down\", \"during\", \"each\", \"few\", \"for\", \"from\", \"further\", \"had\", \"has\", \"have\", \"having\",\n",
        "             \"he\", \"hed\", \"hes\", \"her\", \"here\", \"heres\", \"hers\", \"herself\", \"him\", \"himself\", \"his\", \"how\",\n",
        "             \"hows\", \"i\", \"id\", \"ill\", \"im\", \"ive\", \"if\", \"in\", \"into\", \"is\", \"it\", \"its\", \"itself\",\n",
        "             \"lets\", \"me\", \"more\", \"most\", \"my\", \"myself\", \"nor\", \"of\", \"on\", \"once\", \"only\", \"or\", \"other\", \"ought\",\n",
        "             \"our\", \"ours\", \"ourselves\", \"out\", \"over\", \"own\", \"same\", \"she\", \"shed\", \"shell\", \"shes\", \"should\",\n",
        "             \"so\", \"some\", \"such\", \"than\", \"that\", \"thats\", \"the\", \"their\", \"theirs\", \"them\", \"themselves\", \"then\",\n",
        "             \"there\", \"theres\", \"these\", \"they\", \"theyd\", \"theyll\", \"theyre\", \"theyve\", \"this\", \"those\", \"through\",\n",
        "             \"to\", \"too\", \"under\", \"until\", \"up\", \"very\", \"was\", \"we\", \"wed\", \"well\", \"were\", \"weve\", \"were\",\n",
        "             \"what\", \"whats\", \"when\", \"whens\", \"where\", \"wheres\", \"which\", \"while\", \"who\", \"whos\", \"whom\", \"why\",\n",
        "             \"whys\", \"with\", \"would\", \"you\", \"youd\", \"youll\", \"youre\", \"youve\", \"your\", \"yours\", \"yourself\",\n",
        "             \"yourselves\"]\n",
        "\n",
        "table = str.maketrans('', '', string.punctuation)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "BQVuQrZNkPn9",
        "colab": {}
      },
      "source": [
        "!wget --no-check-certificate \\\n",
        "    https://storage.googleapis.com/learning-datasets/sarcasm.json \\\n",
        "    -O /tmp/sarcasm.json\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Toj7ELTr2TJS",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Download Glove -- project at https://github.com/stanfordnlp/GloVe\n",
        "# on that page you will find the glove twitter dataset\n",
        "# Get it, and upload it to a server where you can access it.\n",
        "# You will want the file called glove.twitter.27B.25d.zip.\n",
        "\n",
        "!wget --no-check-certificate \\\n",
        "    https://[Your Path To]/glove.twitter.27B.25d.zip \\\n",
        "    -O /tmp/glove.zip"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "k7egVHnc5xyM",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Unzip Glove Embeddings\n",
        "import os\n",
        "import zipfile\n",
        "\n",
        "local_zip = '/tmp/glove.zip'\n",
        "zip_ref = zipfile.ZipFile(local_zip, 'r')\n",
        "zip_ref.extractall('/tmp/glove')\n",
        "zip_ref.close()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6VioYI9W6Hfz",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "glove_embeddings = dict()\n",
        "f = open('/tmp/glove/glove.twitter.27B.25d.txt')\n",
        "for line in f:\n",
        "    values = line.split()\n",
        "    word = values[0]\n",
        "    coefs = np.asarray(values[1:], dtype='float32')\n",
        "    glove_embeddings[word] = coefs\n",
        "f.close()\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "K2XSfAtI64D0",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print('Loaded %s word vectors.' % len(glove_embeddings))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "oaLaaqhNkUPd",
        "colab": {}
      },
      "source": [
        "import json\n",
        "from tensorflow.keras.preprocessing.text import Tokenizer\n",
        "from tensorflow.keras.preprocessing.sequence import pad_sequences\n",
        "\n",
        "with open(\"/tmp/sarcasm.json\", 'r') as f:\n",
        "    datastore = json.load(f)\n",
        "\n",
        "\n",
        "sentences = [] \n",
        "labels = []\n",
        "urls = []\n",
        "for item in datastore:\n",
        "    sentence = item['headline'].lower()\n",
        "    sentence = sentence.replace(\",\", \" , \")\n",
        "    sentence = sentence.replace(\".\", \" . \")\n",
        "    sentence = sentence.replace(\"-\", \" - \")\n",
        "    sentence = sentence.replace(\"/\", \" / \")\n",
        "    soup = BeautifulSoup(sentence)\n",
        "    sentence = soup.get_text()\n",
        "    words = sentence.split()\n",
        "    filtered_sentence = \"\"\n",
        "    for word in words:\n",
        "        word = word.translate(table)\n",
        "        if word not in stopwords:\n",
        "            filtered_sentence = filtered_sentence + word + \" \"\n",
        "    sentences.append(filtered_sentence)\n",
        "    labels.append(item['is_sarcastic'])\n",
        "    urls.append(item['article_link'])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "0eJSTTYnkJQd",
        "colab": {}
      },
      "source": [
        "vocab_size = 13200\n",
        "embedding_dim = 25\n",
        "max_length = 50\n",
        "trunc_type='post'\n",
        "padding_type='post'\n",
        "oov_tok = \"<OOV>\"\n",
        "training_size = 23000"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "S1sD-7v0kYWk",
        "colab": {}
      },
      "source": [
        "training_sentences = sentences[0:training_size]\n",
        "testing_sentences = sentences[training_size:]\n",
        "training_labels = labels[0:training_size]\n",
        "testing_labels = labels[training_size:]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "3u8UB0MCkZ5N",
        "colab": {}
      },
      "source": [
        "tokenizer = Tokenizer(num_words=vocab_size, oov_token=oov_tok)\n",
        "tokenizer.fit_on_texts(training_sentences)\n",
        "\n",
        "word_index = tokenizer.word_index\n",
        "print(len(word_index))\n",
        "training_sequences = tokenizer.texts_to_sequences(training_sentences)\n",
        "training_padded = pad_sequences(training_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)\n",
        "\n",
        "testing_sequences = tokenizer.texts_to_sequences(testing_sentences)\n",
        "testing_padded = pad_sequences(testing_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Vpy-QccostKv",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "xs=[]\n",
        "ys=[]\n",
        "cumulative_x=[]\n",
        "cumulative_y=[]\n",
        "total_y=0\n",
        "for word, index in tokenizer.word_index.items():\n",
        "  xs.append(index)\n",
        "  cumulative_x.append(index)\n",
        "  if glove_embeddings.get(word) is not None:\n",
        "    total_y = total_y + 1\n",
        "    ys.append(1)\n",
        "  else:\n",
        "    ys.append(0)\n",
        "  cumulative_y.append(total_y / index)\n",
        "\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WMPs_cG9ubS4",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "fig, ax = plt.subplots(figsize=(12,2))\n",
        "ax.spines['top'].set_visible(False)\n",
        "\n",
        "plt.margins(x=0, y=None, tight=True)\n",
        "#plt.axis([13000, 14000, 0, 1])\n",
        "plt.fill(ys)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "8rc_v2UMvloQ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "plt.plot(cumulative_x, cumulative_y)\n",
        "plt.axis([13000, 14000, .97, .98])\n",
        "print(cumulative_y[-1:])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "nXms4A1K7GlT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "embedding_matrix = np.zeros((vocab_size, embedding_dim))\n",
        "for word, index in tokenizer.word_index.items():\n",
        "    if index > vocab_size - 1:\n",
        "        break\n",
        "    else:\n",
        "        embedding_vector = glove_embeddings.get(word)\n",
        "        if embedding_vector is not None:\n",
        "            embedding_matrix[index] = embedding_vector"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "pYdKKh3T7WFS",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print(embedding_matrix[2])\n",
        "print(tokenizer.word_index)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "GrAlWBKf99Ya",
        "colab": {}
      },
      "source": [
        "# Need this block to get it to work with TensorFlow 2.x\n",
        "import numpy as np\n",
        "training_padded = np.array(training_padded)\n",
        "training_labels = np.array(training_labels)\n",
        "testing_padded = np.array(testing_padded)\n",
        "testing_labels = np.array(testing_labels)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "FufaT4vlkiDE",
        "colab": {}
      },
      "source": [
        "model = tf.keras.Sequential([\n",
        "    tf.keras.layers.Embedding(vocab_size, embedding_dim, weights=[embedding_matrix], trainable=False),\n",
        "    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(embedding_dim, return_sequences=True)),\n",
        "    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(embedding_dim)),\n",
        "    tf.keras.layers.Dense(24, activation='relu'),\n",
        "    tf.keras.layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "adam = tf.keras.optimizers.Adam(learning_rate=0.00001, beta_1=0.9, beta_2=0.999, amsgrad=False)\n",
        "model.compile(loss='binary_crossentropy',optimizer=adam, metrics=['accuracy'])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "XfDt1hmYkiys",
        "colab": {}
      },
      "source": [
        "model.summary()\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "2DTKQFf1kkyc",
        "colab": {}
      },
      "source": [
        "num_epochs = 30\n",
        "history = model.fit(training_padded, training_labels, epochs=num_epochs, validation_data=(testing_padded, testing_labels), verbose=2)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "2HYfBKXjkmU8",
        "colab": {}
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "\n",
        "def plot_graphs(history, string):\n",
        "  plt.plot(history.history[string])\n",
        "  plt.plot(history.history['val_'+string])\n",
        "  plt.xlabel(\"Epochs\")\n",
        "  plt.ylabel(string)\n",
        "  plt.legend([string, 'val_'+string])\n",
        "  plt.show()\n",
        "  \n",
        "plot_graphs(history, \"accuracy\")\n",
        "plot_graphs(history, \"loss\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "7SBdAZAenvzL",
        "colab": {}
      },
      "source": [
        "reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])\n",
        "\n",
        "def decode_sentence(text):\n",
        "    return ' '.join([reverse_word_index.get(i, '?') for i in text])\n",
        "\n",
        "print(decode_sentence(training_padded[2]))\n",
        "print(training_sentences[2])\n",
        "print(labels[2])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "c9MqihtEkzQ9",
        "colab": {}
      },
      "source": [
        "e = model.layers[0]\n",
        "weights = e.get_weights()[0]\n",
        "print(weights.shape) # shape: (vocab_size, embedding_dim)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "x79hCiBscirR",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print(reverse_word_index[2])\n",
        "print(weights[2])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "LoBXVffknldU",
        "colab": {}
      },
      "source": [
        "import io\n",
        "\n",
        "out_v = io.open('vecs.tsv', 'w', encoding='utf-8')\n",
        "out_m = io.open('meta.tsv', 'w', encoding='utf-8')\n",
        "for word_num in range(1, vocab_size):\n",
        "  word = reverse_word_index[word_num]\n",
        "  embeddings = weights[word_num]\n",
        "  out_m.write(word + \"\\n\")\n",
        "  out_v.write('\\t'.join([str(x) for x in embeddings]) + \"\\n\")\n",
        "out_v.close()\n",
        "out_m.close()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "U4eZ5HtVnnEE",
        "colab": {}
      },
      "source": [
        "try:\n",
        "  from google.colab import files\n",
        "except ImportError:\n",
        "  pass\n",
        "else:\n",
        "  files.download('vecs.tsv')\n",
        "  files.download('meta.tsv')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "cG8-ArY-qDcz",
        "colab": {}
      },
      "source": [
        "test_sentences = [\"It Was, For, Uh, Medical Reasons, Says Doctor To Boris Johnson, Explaining Why They Had To Give Him Haircut\",\n",
        "                  \"It's a beautiful sunny day\",\n",
        "                  \"I lived in Ireland, so in High School they made me learn to speak and write in Gaelic\",\n",
        "                  \"Census Foot Soldiers Swarm Neighborhoods, Kick Down Doors To Tally Household Sizes\"]\n",
        "\n",
        "#test_sentences = [\"granny starting to fear spiders in the garden might be real\", \n",
        "# \"game of thrones season finale showing this sunday night\", \n",
        "# \"TensorFlow book will be a best seller\"]\n",
        "sequences = tokenizer.texts_to_sequences(test_sentences)\n",
        "#print(sequences)\n",
        "padded = pad_sequences(sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)\n",
        "#print(padded)\n",
        "\n",
        "predictions = model.predict(padded)\n",
        "#print(predictions[:, max_length-1])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Vuvdj9QOIINq",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print(predictions)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Pz56oE8QNoNK",
        "colab_type": "text"
      },
      "source": [
        ""
      ]
    }
  ]
}
